/*
 * 描述： <描述>
 * 修改人： rain
 * 修改时间： 2016年8月8日
 * 项目： rainhy-servicelogger
 */
package com.rainhy.servicelogger.context;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import com.rainhy.core.util.AssertUtils;
import com.rainhy.servicelogger.logger.ServiceLogger;

/**
 * 业务日志容器日志建造者工厂
 * 
 * @author rain
 * @version [版本号, 2016年8月8日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class ServiceLoggerContextBuilderFactory extends ServiceLoggerContextConfigurator {
    
    /** 业务日志 */
    private MultiValueMap<Class<?>, ServiceLogger> serviceLoggerMapping = new LinkedMultiValueMap<>();
    
    /** 业务日志建造者 */
    private Map<String, ServiceLoggerBuilder> serviceLoggerBuilderMapping = new HashMap<>();
    
    @Override
    public void afterPropertiesSet() throws Exception {
        super.afterPropertiesSet();
        Map<String, ServiceLoggerBuilder> serviceLoggerBuilderMap = this.applicationContext.getBeansOfType(ServiceLoggerBuilder.class);
        AssertUtils.notEmpty(serviceLoggerBuilderMap, "没有获取到一个[业务日志建造者].请实现一个 ServiceLoggerBuilder 接口,注入进来.");
        this.serviceLoggerBuilderMapping.putAll(serviceLoggerBuilderMap);
        
        for (ServiceLoggerBuilder serviceLoggerBuilder : this.serviceLoggerBuilderMapping.values()) {
            logger.debug("    加载业务日志建造者: {}", serviceLoggerBuilder.getClass().getName());
        }
    }
    
    /** 根据业务日志类型获取业务日志 */
    public List<ServiceLogger> getServiceLoggers(Class<?> loggerType) {
        AssertUtils.notNull(loggerType, " 业务日志类型不能为 null");
        
        //从如果已经存在实例化的logger则直接提取
        if (!serviceLoggerMapping.containsKey(loggerType)) {
            if (MapUtils.isNotEmpty(serviceLoggerBuilderMapping)) {
                for (ServiceLoggerBuilder serviceLoggerBuilder : serviceLoggerBuilderMapping.values()) {
                    ServiceLogger serviceLogger = serviceLoggerBuilder.build(loggerType);
                    if (serviceLogger != null) {
                        serviceLoggerMapping.add(loggerType, serviceLogger);
                    }
                }
            }
            AssertUtils.contains(serviceLoggerMapping, loggerType, "没有找到适合[{}]类型的业务日志建造者.", loggerType.getName());
        }
        
        return serviceLoggerMapping.get(loggerType);
    }
    
}
